package com.zdlt.admin.api.controller;

import com.zdlt.admin.api.common.LoginInfo;
import com.zdlt.admin.api.common.VueResult;
import com.zdlt.admin.api.common.util.FileUtil;
import com.zdlt.admin.api.domain.*;
import com.zdlt.admin.api.dto.*;
import com.zdlt.admin.api.mapper.ArticleMapper;
import com.zdlt.admin.api.mapper.FollowMapper;
import com.zdlt.admin.api.mapper.ImageInfoMapper;
import com.zdlt.admin.api.mapper.SystemUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 头条管理系统接口服务类
 */
@Slf4j
@CrossOrigin
@RequestMapping
@RestController
public class AdminApiController {
    @Value("${web.upload-path}")
    private String uploadPath;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private ImageInfoMapper imageInfoMapper;

    @Autowired
    private SystemUserMapper systemUserMapper;

    @Autowired
    private FollowMapper followMapper;

    /**
     * 登录（模拟token）
     *
     * @return
     */
    @ResponseBody
    @PostMapping("/mp/v1_0/authorizations")
    public VueResult<LoginInfo> authorizations() {
        SystemUser systemUser = systemUserMapper.get(1L);

        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setId(systemUser.getId());
        loginInfo.setName(systemUser.getName());
        loginInfo.setMobile(systemUser.getMobile());
        loginInfo.setEmail(systemUser.getEmail());
        loginInfo.setIntro(systemUser.getIntro());
        loginInfo.setPhoto(systemUser.getPhoto());
        loginInfo.setToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ");
        loginInfo.setRefreshToken("");

        VueResult<LoginInfo> result = new VueResult<>();
        result.setMessage("OK");
        result.setData(loginInfo);
        return result;
    }

    /**
     * 查询当前登录用户的个人资料
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/mp/v1_0/user/profile")
    public VueResult<LoginInfo> getUserProfile() {
        SystemUser systemUser = systemUserMapper.get(1L);

        LoginInfo loginInfo = new LoginInfo();
        loginInfo.setId(systemUser.getId());
        loginInfo.setName(systemUser.getName());
        loginInfo.setMobile(systemUser.getMobile());
        loginInfo.setEmail(systemUser.getEmail());
        loginInfo.setIntro(systemUser.getIntro());
        loginInfo.setPhoto(systemUser.getPhoto());
        loginInfo.setToken("eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ");
        loginInfo.setRefreshToken("");

        VueResult<LoginInfo> result = new VueResult<>();
        result.setMessage("OK");
        result.setData(loginInfo);
        return result;
    }

    /**
     * 修改个人资料
     *
     * @param userDto 修改信息
     * @return
     */
    @ResponseBody
    @PatchMapping("/mp/v1_0/user/profile")
    public VueResult<SystemUser> updateUser(@RequestBody UserDto userDto) {
        // 从token获取用户信息
        SystemUser systemUser = new SystemUser();
        systemUser.setId(1L);
        systemUser.setName(userDto.getName());
        systemUser.setEmail(userDto.getEmail());
        systemUser.setIntro(userDto.getIntro());
        systemUserMapper.update(1L, systemUser);

        VueResult vueResult = new VueResult();
        vueResult.setMessage("OK");
        vueResult.setData(systemUser);
        return vueResult;
    }

    /**
     * 分页查询文章列表
     *
     * @param query 查询条件
     * @return
     */
    @ResponseBody
    @GetMapping("/mp/v1_0/articles")
    public VueResult<PageResult<Article>> getArticles(ArticleQuery query) {
        query.setPage_index((query.getPage() - 1) * query.getPer_page());
        List<Article> articles = articleMapper.query(query);
        int articleListCount = articleMapper.count(query);
        for (Article article : articles) {
            Cover cover = new Cover();
            if (article.getImages() != null) {
                String[] imageArr = article.getImages().split(",");
                cover.setImages(Arrays.asList(imageArr));
            }
            cover.setType(article.getCoverType());
            article.setCover(cover);
        }

        PageResult pageResult = new PageResult();
        pageResult.setPage(query.getPage());
        pageResult.setPerPage(query.getPer_page());
        pageResult.setTotal_count(articleListCount);
        pageResult.setResults(articles);

        VueResult<PageResult<Article>> vueResult = new VueResult<>();
        vueResult.setMessage("OK");
        vueResult.setData(pageResult);
        return vueResult;
    }

    /**
     * 文章频道列表
     *
     * @return
     */
    @ResponseBody
    @GetMapping("/mp/v1_0/channels")
    public VueResult<List<ArticleChannel>> getArticleChannels() {
        List<ArticleChannel> channels = new ArrayList<>();
        ArticleChannel channel1 = new ArticleChannel(1L, "Java");
        ArticleChannel channel2 = new ArticleChannel(2L, "C++");
        ArticleChannel channel3 = new ArticleChannel(3L, "Python");

        channels.add(channel1);
        channels.add(channel2);
        channels.add(channel3);

        VueResult<List<ArticleChannel>> vueResult = new VueResult<>();
        vueResult.setMessage("OK");
        vueResult.setData(channels);
        return vueResult;
    }

    /**
     * 删除文章
     *
     * @param articleId 文章id
     * @return
     */
    @ResponseBody
    @DeleteMapping("/mp/v1_0/articles/{articleId}")
    public VueResult deleteArticle(@PathVariable("articleId") String articleId) {
        VueResult vueResult = new VueResult();
        int ret = articleMapper.delete(articleId);
        vueResult.setData(ret);
        vueResult.setMessage("OK");
        return vueResult;
    }

    /**
     * 发布文章
     *
     * @param draft   是否存入草稿
     * @param article 文章信息
     * @return
     */
    @ResponseBody
    @PostMapping("/mp/v1_0/articles")
    public VueResult addArticle(
            @RequestParam(value = "draft", defaultValue = "false") boolean draft,
            @RequestBody Article article) {
        article.setStatus(draft ? 0 : 1);
        article.setPubdate(new Date());
        if (article != null && article.getCover() != null) {
            if (article.getCover().getImages() != null) {
                List<String> images = article.getCover().getImages();
                article.setImages(StringUtils.join(images.toArray(), ","));
            }
            article.setCoverType(article.getCover().getType());
        }
        articleMapper.insert(article);

        VueResult vueResult = new VueResult();
        vueResult.setMessage("OK");
        vueResult.setData(article.getId());
        return vueResult;
    }

    /**
     * 修改文章
     *
     * @param id      文章id
     * @param draft   是否存入草稿
     * @param article 文章更新信息
     * @return
     */
    @ResponseBody
    @PutMapping("/mp/v1_0/articles/{id}")
    public VueResult updateArticle(
            @PathVariable("id") String id,
            @RequestParam("draft") boolean draft,
            @RequestBody Article article) {
        article.setStatus(draft ? 0 : 1);
        article.setPubdate(new Date());
        if (article != null && article.getCover() != null) {
            article.setImages(StringUtils.join(article.getCover().getImages(), ","));
            article.setCoverType(article.getCover().getType());
        }
        articleMapper.update(id, article);
        VueResult vueResult = new VueResult();
        vueResult.setMessage("OK");
        vueResult.setData(id);
        return vueResult;
    }

    /**
     * 查询文章详情
     *
     * @param id 文章id
     * @return
     */
    @GetMapping("/mp/v1_0/articles/{id}")
    @ResponseBody
    public VueResult<Article> getArticle(@PathVariable("id") Long id) {
        Article article = articleMapper.get(id);
        Cover cover = new Cover();
        if (article != null) {
            if (article.getImages() != null) {
                String[] imageArr = article.getImages().split(",");
                cover.setImages(Arrays.asList(imageArr));
            }
            cover.setType(article.getCoverType());
            article.setCover(cover);
        }
        VueResult<Article> vueResult = new VueResult<>();
        vueResult.setMessage("OK");
        vueResult.setData(article);
        return vueResult;
    }

    /**
     * 修改评论状态
     *
     * @param articleId     文章id
     * @param commentStatus 评论状态
     * @return
     */
    @ResponseBody
    @PutMapping("/mp/v1_0/comments/status")
    public VueResult updateComment(
            @RequestParam("articleId") String articleId,
            @RequestBody CommentStatus commentStatus) {
        if (commentStatus != null && commentStatus.getAllowComment() != null) {
            Article article = new Article();
            article.setCommentStatus(commentStatus.getAllowComment());
            articleMapper.update(articleId, article);
        }
        VueResult vueResult = new VueResult();
        vueResult.setMessage("OK");
        return vueResult;
    }

    /**
     * 分页查询图片素材列表
     *
     * @param collect 全部 or 收藏
     * @param page    页码
     * @param perPage 页大小
     * @return
     */
    @ResponseBody
    @GetMapping("/mp/v1_0/user/images")
    public VueResult<PageResult<ImageInfo>> getImages(
            @RequestParam(value = "collect", defaultValue = "false") Boolean collect,
            @RequestParam(value = "page", defaultValue = "1") Integer page,
            @RequestParam(value = "perPage", defaultValue = "20") Integer perPage) {
        int pageIndex = (page - 1) * perPage;

        VueResult<PageResult<ImageInfo>> vueResult = new VueResult<>();
        PageResult<ImageInfo> pageResult = new PageResult<>();

        List<ImageInfo> list = imageInfoMapper.list(collect, pageIndex, perPage);
        int count = imageInfoMapper.count(collect);
        pageResult.setResults(list);
        pageResult.setTotal_count(count);
        pageResult.setPerPage(perPage);
        pageResult.setPage(pageIndex);
        vueResult.setData(pageResult);
        vueResult.setMessage("OK");
        return vueResult;
    }

    /**
     * 上传图片素材
     *
     * @param file
     * @return
     */
    @ResponseBody
    @PostMapping("/mp/v1_0/user/images")
    public VueResult uploadImage(@RequestParam("image") MultipartFile file, HttpServletRequest request) {
        String filePath;
        try {
            filePath = FileUtil.upload(file, request, uploadPath);
        } catch (IOException e) {
            VueResult vueResult = new VueResult();
            vueResult.setMessage("上传失败");
            return vueResult;
        }

        ImageInfo imageInfo = new ImageInfo();
        imageInfo.setCollect(false);
        imageInfo.setUrl(filePath);
        imageInfoMapper.insert(imageInfo);

        VueResult vueResult = new VueResult();
        vueResult.setMessage("OK");
        vueResult.setData(filePath);
        return vueResult;
    }

    /**
     * 收藏图片素材
     *
     * @param imageId 图片素材id
     * @param collect 收藏 or 取消收藏
     * @return
     */
    @ResponseBody
    @PutMapping("/mp/v1_0/user/images/{imageId}")
    public VueResult collect(@PathVariable("imageId") Integer imageId, @RequestBody CollectReq collect) {

        ImageInfo imageInfo = new ImageInfo();
        imageInfo.setId(imageId);
        imageInfo.setCollect(collect.isCollect());
        imageInfoMapper.update(imageInfo);

        VueResult vueResult = new VueResult();
        vueResult.setMessage("OK");
        return vueResult;
    }

    /**
     * 删除图片素材
     *
     * @param id 图片素材id
     * @return
     */
    @ResponseBody
    @DeleteMapping("/mp/v1_0/user/images/{id}")
    public VueResult deleteImage(@PathVariable("id") Integer id) {
        imageInfoMapper.delete(id);
        VueResult vueResult = new VueResult();
        vueResult.setMessage("OK");
        return vueResult;
    }

    /**
     * 分页查询粉丝列表
     *
     * @param currentPage
     * @param pageSize
     * @return
     */
    @ResponseBody
    @GetMapping("/mp/v1_0/followers")
    public VueResult<PageResult<FansDto>> followers(
            @RequestParam("page") int currentPage,
            @RequestParam("per_page") int pageSize) {
        int pageIndex = (currentPage - 1) * pageSize;
        // 根据token获取用户id
        Long userId = 1L;
        List<SystemUser> users = followMapper.page(userId, pageIndex, pageSize);
        int count = followMapper.count(userId);

        // 查询当前用户的关注
        List<Long> allFollowed = followMapper.allFollowed(userId);

        List<FansDto> fansDtoList = new ArrayList<>();
        for (SystemUser user : users) {
            FansDto fansDto = new FansDto();
            fansDto.setId(user.getId());
            fansDto.setName(user.getName());
            fansDto.setPhoto(user.getPhoto());
            // 当前用户是否已关注该粉丝
            fansDto.setFollowed(allFollowed.contains(user.getId()));
            fansDtoList.add(fansDto);
        }

        PageResult<FansDto> pageResult = new PageResult<>();
        pageResult.setPage(currentPage);
        pageResult.setPerPage(pageSize);
        pageResult.setTotal_count(count);
        pageResult.setResults(fansDtoList);
        VueResult<PageResult<FansDto>> vueResult = new VueResult<>();
        vueResult.setMessage("OK");
        vueResult.setData(pageResult);
        return vueResult;
    }

    /**
     * 关注
     *
     * @param fanId 粉丝id
     * @return
     */
    @ResponseBody
    @PostMapping("/mp/v1_0/follow")
    public VueResult follow(@RequestParam("fanId") Long fanId) {
        // 根据token获取当前登录用户id
        Long userId = 1L;
        // 查询当前登录用户是否关注该粉丝
        int count = followMapper.relationship(fanId, userId);
        if (count > 0) {
            // 取消关注
            followMapper.unFollow(fanId, userId);
        } else {
            // 关注操作
            Follow follow = new Follow();
            follow.setUserId(fanId);
            follow.setFansId(userId);
            follow.setCreateTime(new Date());
            followMapper.insert(follow);
        }
        VueResult vueResult = new VueResult();
        vueResult.setMessage("OK");
        return vueResult;
    }
}
